
package UI;

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSeparator;
import javax.swing.ListSelectionModel;
import javax.swing.SwingConstants;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

import model.InputProcess;
import model.ProcessType;

/**
 * ListPanel create Listmodel for the user choice of processes.
 * 
 * @author Sydney Lin
 * @version 1.0
 */
@SuppressWarnings("serial")
public class ListPanel extends JPanel implements ListSelectionListener
{
  /**
   * JList for swing panel.
   */
  private final JList my_list;
  
  /**
   * The list model.
   */
  private DefaultListModel my_list_model;
  
  /**
   * Array of all process types.
   */
  //private static final String[] processString = {"Calculating", "Consumer & Producer", "IO"};
  private static final ProcessType[] my_process_type = {ProcessType.CALCULATING, ProcessType.IO, ProcessType.PRODUCER_CONSUMER};
  
  /**
   * The string "Delete".
   */
  private static final String deleteString = "Delete";
  
  /**
   * the deleteButton
   */
  private JButton deleteButton;

  /**
   * Construct a ListPanel.
   */
  public ListPanel()
  {
    super(new BorderLayout());
    // initialized
    my_list_model = new DefaultListModel();
    my_list_model.addElement(new InputProcess(ProcessType.PRODUCER_CONSUMER));
    my_list_model.addElement(new InputProcess(ProcessType.CALCULATING));
    my_list_model.addElement(new InputProcess(ProcessType.IO));
    my_list_model.addElement(new InputProcess(ProcessType.IO));
    my_list_model.addElement(new InputProcess(ProcessType.PRODUCER_CONSUMER));

    // Create the list and put it in a scroll pane.
    my_list = new JList(my_list_model);
    my_list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    my_list.setSelectedIndex(0);
    my_list.addListSelectionListener(this);
    my_list.setVisibleRowCount(5);
    final JScrollPane list_scroll_pane = new JScrollPane(my_list);
    final JButton[] process_button = new JButton[my_process_type.length];
    ButtonListener button_listener;
    
    for (int i = 0; i < my_process_type.length; i++)
    {
      process_button[i] = new JButton(my_process_type[i].toString());
      button_listener = new ButtonListener(my_process_type[i]);
      process_button[i].setActionCommand(my_process_type[i].toString());
      process_button[i].addActionListener(button_listener);
      // processButton[b].setEnabled(false);
    }

    deleteButton = new JButton(deleteString);
    deleteButton.setActionCommand(deleteString);
    deleteButton.addActionListener(new DeleteListener());

    // Create a panel that uses BoxLayout.
    final JPanel button_pane = new JPanel();
    button_pane.setLayout(new BoxLayout(button_pane, BoxLayout.LINE_AXIS));
    button_pane.add(deleteButton);
    button_pane.add(Box.createHorizontalStrut(5));
    button_pane.add(new JSeparator(SwingConstants.VERTICAL));
    button_pane.add(Box.createHorizontalStrut(5));

    for (JButton b : process_button)
    {
      button_pane.add(b);
    }
    button_pane.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));

    add(list_scroll_pane, BorderLayout.CENTER);
    add(button_pane, BorderLayout.PAGE_END);
  }

  /**
   * DeleteListener listens to DeleteButtons.
   * @author Sydney Lin 
   * @version 1.0
   */
  class DeleteListener implements ActionListener
  {
    /**
     * {@inheritDoc}
     */
    public void actionPerformed(final ActionEvent the_event)
    {
      // This method can be called only if
      // there's a valid selection
      // so go ahead and remove whatever's selected.
      int index = my_list.getSelectedIndex();
      my_list_model.remove(index);

      final int size = my_list_model.getSize();

      if (size == 0)
      { // Nobody's left, disable Delete.
        deleteButton.setEnabled(false);

      }
      else
      { // Select an index.
        if (index == my_list_model.getSize())
        {
          // removed item in last position
          index--;
        }

        my_list.setSelectedIndex(index);
        my_list.ensureIndexIsVisible(index);
      }
    }
  }

  /**
   * This listener is for the processbutton.
   * @author Sydney Lin
   * @version 1.0
   */
  class ButtonListener implements ActionListener
  {
    /**
     * The process type of this button.
     */
    private final ProcessType my_process_type;

    /**
     * Construct a ButtonListener for a specific process type.
     * @param the_process_type The process type.
     */
    public ButtonListener(final ProcessType the_process_type)
    {
      my_process_type = the_process_type;
    }

    /**
     * {@inheritDoc}
     */
    public void actionPerformed(final ActionEvent the_event)
    {
      int index = my_list.getSelectedIndex(); // get selected index
      if (index == -1)
      { // no selection, so insert at beginning
        index = 0;
      }
      else
      { // add after the selected item
        index++;
      }

      my_list_model.insertElementAt(new InputProcess(my_process_type), index);
      // If we just wanted to add to the end, we'd do this:
      // listModel.addElement(addedProcess.getText());

      // Select the new item and make it visible.
      my_list.setSelectedIndex(index);
      my_list.ensureIndexIsVisible(index);

    }
  }

  /**
   * {@inheritDoc}
   * @param the_event The event that characterizes the changes.
   */
  public void valueChanged(final ListSelectionEvent the_event)
  {
    if (!the_event.getValueIsAdjusting())
    {

      if (my_list.getSelectedIndex() == -1)
      {
        // No selection, disable delete button.
        deleteButton.setEnabled(false);

      }
      else
      {
        // Selection, enable the delete button.
        deleteButton.setEnabled(true);
      }
    }
  }
  
  /**
   * 
   * @return The list of processes.
   */
  public DefaultListModel getProcessList()
  {
    return my_list_model;
  }

  /**
   * Create the GUI and show it. For thread safety, this method should be
   * invoked from the event-dispatching thread.
   */
  /*
   * private static void createPanel() { //Create and set up the Panel.
   * 
   * 
   * 
   * //Create and set up the content pane. JComponent newContentPane = new
   * ListPanel(); newContentPane.setOpaque(true); //content panes must be opaque
   * frame.setContentPane(newContentPane);
   * 
   * //Display the window. frame.pack(); frame.setVisible(true); }
   * 
   * public static void main(String[] args) { //Schedule a job for the
   * event-dispatching thread: //creating and showing this application's GUI. //
   * javax.swing.SwingUtilities.invokeLater(new Runnable() { // public void
   * run() { createAndShowGUI(); // } //}); }
   */
}
